#include <nice2d/application.h>
#include <nice2d/background.h>
#include <nice2d/deserializerfactory.h>
#include <nice2d/widgets/desktop.h>
#include <nice2d/widgets/panel.h>
#include <nice2d/widgets/titlebar.h>

IMPLEMENT_OBJECT(PanelStyle, LayoutStyle)

PanelStyle::PanelStyle()
{
    normalBackground = Background::create(sf::Color(60, 60, 60));
    titleBarStyle = std::make_shared<TitleBarStyle>();
    titleBarStyle->normalBackground = Background::create(sf::Color(90, 90, 90));
    titleBarStyle->hoverBackground = Background::create(sf::Color(100, 100, 100));
    titleBarStyle->pressedBackground = Background::create(sf::Color(100, 100, 100));
    titleBarStyle->titleStyle->textColor = sf::Color::White;

    contentStyle = std::make_shared<ControlStyle>();
}

PanelStyle::~PanelStyle()
{
}

PTree PanelStyle::serialize()
{
    PTree node;
    SERIALIZE_BASE_OBJECT(node, LayoutStyle)
    node.add_child("titleBarStyle", titleBarStyle->serializeThisClass());
    node.add_child("contentStyle", contentStyle->serializeThisClass());
    return node;
}

void PanelStyle::deserialize(const PTree &node)
{
    DESERIALIZE_BASE_OBJECT(node, LayoutStyle)
    titleBarStyle = DeserializerFactory::deserialize<TitleBarStyle>("titleBarStyle", node);
    contentStyle = DeserializerFactory::deserialize<ControlStyle>("contentStyle", node);
}

void PanelStyle::sync()
{
}

class PanelData
{
public:
    Panel *panel = nullptr;
    std::shared_ptr<TitleBar> titleBar;
    std::shared_ptr<Control> content;

    PanelData(Panel *thisPanel):
        panel(thisPanel)
    {
    }

    void clickedCloseButton()
    {
        panel->hide();
    }
};

IMPLEMENT_OBJECT(Panel, VBoxLayout)

Panel::Panel():
    data(new PanelData(this))
{
    auto desktop = GET_APPLICATION_COMPONENT(Desktop);
    auto style = desktop->getControlStyle("Panel");
    setControlStyle(style);
}

std::shared_ptr<Panel> Panel::create(const sf::String &title, ControlPointer content)
{
    if (!content)
        return nullptr;

    auto panel = std::make_shared<Panel>();
    panel->data->titleBar = TitleBar::create(title);
    panel->data->titleBar->setDraggableTarget(panel);
    panel->data->content = content;
    panel->addWidget(panel->data->titleBar);
    panel->addWidget(panel->data->content);
    panel->setLayoutResizeRule(LayoutResizeRule_ResizeLayout);

    panel->data->titleBar->setWidth(content->getWidth());
    panel->data->titleBar->closeButtonPressed.connect(std::bind(&PanelData::clickedCloseButton,
                                                                panel->data.get()));

    auto style = panel->getTemplateStyle<PanelStyle>();
    panel->data->titleBar->setControlStyle(style->titleBarStyle);
    panel->data->content->setControlStyle(style->contentStyle);
    return panel;
}

Panel::~Panel()
{
}

void Panel::setTitle(const sf::String &title)
{
    data->titleBar->setTitle(title);
}

sf::String Panel::getTitle() const
{
    return data->titleBar->getTitle();
}

void Panel::adjust()
{
    auto contentSize = data->content->getSize();
    if (contentSize.x > 0) {
        data->titleBar->setWidth(contentSize.x);
        data->titleBar->setLayoutResizeRule(LayoutResizeRule_ResizeControls);
    }
    VBoxLayout::adjust();
}

void Panel::onStyleChanged()
{
    auto style = getTemplateStyle<PanelStyle>();
    setBackground(style->normalBackground);
}
